Read Buf

Read Buf

如何改善你的 Zig 语言服务器体验?

Zig 生态系统仍在发展,许多重要的构建模块尚未最终定型。

一个显著的例子是当前的语言服务器情况:ZLS 是由社区努力开发的出色工具,能够跟上语言的变化(他们有一些聪明的方法来自动化这个过程),但有一个大缺陷:它无法解析复杂的 comptime 表达式。

结果是 ZLS 可以为您提供解析器级别的诊断(从语法错误到未使用变量错误),但当您尝试将错误类型的参数传递给函数或尝试将 usize 分配给 f64 时,它无法显示错误。

从 ZLS 获取保存时构建的诊断

您可以配置 ZLS 在保存时运行构建脚本。如果构建过程中出现错误,ZLS 将能在编辑器中显示这些错误,就像任何其他诊断一样。

有了这个系统,您就不需要再切换到另一个终端标签来查看构建错误了。

以下是具体操作步骤。

1. 配置 ZLS 在保存时运行构建步骤

注意:如果您通过编辑器的包管理器获取 ZLS,您可能需要查看如何提供配置选项,因为这可能与下面描述的正常程序不同。

运行 ZLS 可执行文件,并让它告诉您配置文件的位置:

$ zls --show-config-path
/home/kristoff/.config/zls.json

请注意,在其他操作系统上,您可能会得到不同的答案(例如在 macOS 上,配置文件位于 “Application Support” 下)。

找到路径后,编辑配置文件,添加以下键:

{
  "enable_build_on_save": true,
  "build_on_save_step": "check"
}

第二个设置不一定非得是 “check”,实际上不定义它将默认运行构建脚本的安装步骤,但稍后我们会看到为什么为此专门设置一个步骤是方便的。

2. 向您的 build.zig 添加检查步骤

这部分更与您的具体项目相关,但大致思路是:无论您如何定义主可执行文件/模块/库,都需要在一个名

为 check 的新步骤中再次定义它。

我将使用 zig init 自动生成的可执行文件定义步骤作为示例。

// 这是一个可执行文件定义示例,
// 无需复制。
const exe = b.addExecutable(.{
    .name = "foo",
    .root_source_file = b.path("src/main.zig"),
    .target = target,
    .optimize = optimize,
});

// 定义依赖项的其他代码可能会在这里。

b.installArtifact(exe);

// 这是有趣的部分开始的地方。
// 如您所见,我们重新定义了相同的
// 可执行文件,但将其绑定到一个
// 专门的构建步骤。
const exe_check = b.addExecutable(.{
    .name = "foo",
    .root_source_file = b.path("src/main.zig"),
    .target = target,
    .optimize = optimize,
});

// 定义依赖项的其他代码可能会在这里。

// 这两行代码您可能需要复制
// (确保重命名 'exe_check')
const check = b.step("check", "Check if foo compiles");
check.dependOn(&exe_check.step);

第二个可执行文件定义的关键点是我们要求构建它,但不安装它。如果您查看第一部分的最后一行,您会看到我们在原始可执行文件上调用了 b.installArtifact,但对于绑定到 “check” 步骤的可执行文件,我们没有。

这一行差异将对构建结果产生重大影响,因为它将 -fno-emit-bin 标志添加到编译器调用中,意味着 Zig 将分析您的代码(并报告任何错误),但不会调用 LLVM,因为您无意安装可执行文件。

结果是,您将很快得到诊断,因为不必经过 “LLVM Emit Code…” 阶段。

完成这些后,重启编辑器(或至少 ZLS),保存包含错误的文件,享受新的快速诊断体验。

未来更美好

通过一些更改,您可以更接近完整的开发者体验,但这还不是终点。

Zig 项目仍在忙于开发关键的编译器基础设施,还需要一些时间才能超越目前的 ZLS,但我们确实在路线图上计划为开发者提供一流的开发工具,就像 Zig 已经为您提供了最先进的编译器工具链一样。

我们路线图上的下一个大项目是从调试构建管道中移除 LLVM,以大幅加快调试构建速度。之后,增量编译将把这些速度提升转化为任意大项目的即时重建。为实现这个目标,我们计划在编译之间保持编译器运行,以便在内存中保留所有必要状态,仅重新分析、重新编译并将项目中更改的部分打补丁到最终可执行文件中。

一旦该系统就位,我们计划让 Zig 编译器回答有关编译项目的各种问题,包括(但不限于)LSP 提供代码智能功能所需的内容。

在此之前,ZLS 以美妙的方式填补了空白,我个人对所有社区成员在这段时间内的工作深表感谢,特别是已故的 Alex Naskos。

如果您想帮助我们更快地实现完整的开发者体验,请考虑捐赠给 Zig 软件基金会。今年早些时候,Andrew 公布了我们的财务状况,我们的收入中超过 90% 用于支付在 Zig 项目上工作的开发者,使您的捐款成为我们更快达到 v1.0 的有效方式。